package com.csun.dsms.controller;

import com.csun.dsms.comment.base.enums.ErrorCodeEnum;
import com.csun.dsms.comment.base.exception.BusinessException;
import com.csun.dsms.comment.core.annotation.Authorization;
import com.csun.dsms.comment.core.annotation.CurrentUser;
import com.csun.dsms.comment.core.annotation.ValidateAnnotation;
import com.csun.dsms.comment.core.support.CsunMessageSource;
import com.csun.dsms.comment.core.utils.wrapper.WrapMapper;
import com.csun.dsms.comment.core.utils.wrapper.Wrapper;
import com.csun.dsms.enums.DisabilityDetailsEnum;
import com.csun.dsms.enums.DisabilityTypeEnum;
import com.csun.dsms.model.domain.DsmsPoor;
import com.csun.dsms.model.domain.DsmsUnit;
import com.csun.dsms.model.domain.DsmsPoorChange;
import com.csun.dsms.model.domain.DsmsUser;
import com.csun.dsms.model.dto.poor.ApplyPoorDto;
import com.csun.dsms.model.dto.poor.ModifyPoorStatusDto;
import com.csun.dsms.model.dto.poor.PoorDto;
import com.csun.dsms.model.dto.poor.PoorQueryDto;
import com.csun.dsms.model.vo.poor.PoorChangeVo;
import com.csun.dsms.model.vo.poor.PoorVo;
import com.csun.dsms.service.DsmsPoorChangeService;
import com.csun.dsms.service.DsmsPoorService;
import com.csun.dsms.service.DsmsUnitService;
import com.csun.dsms.utils.DateUtil;
import com.csun.dsms.utils.ReadExcelUtils;
import com.csun.dsms.validator.DsmsPoorAddValidator;
import com.csun.dsms.validator.DsmsPoorEditValidator;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.transaction.annotation.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author chisj chisj@foxmail.com
 * @version 1.0.0
 * @date 2021-09-16 16:30
 * @description: 特困人员管理拦截器
 */
@Slf4j
@RestController
@RequestMapping("/poor")
public class DsmsPoorController {

    @Resource
    private CsunMessageSource csunMessageSource;
    @Resource
    private DsmsPoorService dsmsPoorService;
    @Resource
    private DsmsPoorChangeService dsmsPoorChangeService;
    @Resource
    private DsmsUnitService dsmsUnitService;

    /**
     * 查询特困人员列表.
     *
     * @param poorQueryDto the poor query dto
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/queryListWithPage")
    public Wrapper queryListWithPage(@RequestBody PoorQueryDto poorQueryDto) {
        int save = dsmsPoorService.save(null);

        List<PoorVo> poorVoList = dsmsPoorService.queryListWithPage(poorQueryDto);

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), new PageInfo(poorVoList));
    }

    /**
     * 新增特困人员
     *
     * @param poorDto the poor dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/save")
    public Wrapper save(@CurrentUser DsmsUser login,
                        @Validated(DsmsPoorAddValidator.class) @RequestBody PoorDto poorDto,
                        BindingResult br) {

        Integer result = dsmsPoorService.save(poorDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null), result);
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 修改特困人员信息
     *
     * @param login   the login user
     * @param poorDto the poor dto
     * @return the wrapper.
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/edit")
    public Wrapper edit(@CurrentUser DsmsUser login,
                        @Validated(DsmsPoorEditValidator.class) @RequestBody PoorDto poorDto,
                        BindingResult br) {

        Integer result = dsmsPoorService.edit(poorDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 通过Id查询特困人员信息.
     *
     * @param poorId the poor id
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/showById/{poorId}")
    public Wrapper showById(@PathVariable Long poorId) {

        PoorVo poorVo = dsmsPoorService.showById(poorId);

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), poorVo);
    }

    /**
     * 通过Id删除特困人员信息.
     *
     * @param poorId the poor id
     * @return the wrapper
     */
    @Authorization
    @PostMapping(value = "/deleteById/{poorId}")
    public Wrapper deleteById(@PathVariable Long poorId) {

        int result = dsmsPoorService.deleteById(poorId);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 根据Id修改特困人员信息.
     *
     * @param modifyPoorStatusDto the modify user status dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/modifyPoorStatusById")
    public Wrapper modifyPoorStatusById(@CurrentUser DsmsUser login,
                                        @Valid @RequestBody ModifyPoorStatusDto modifyPoorStatusDto) {

        DsmsPoor dsmsPoor = new DsmsPoor();
        dsmsPoor.setId(modifyPoorStatusDto.getPoorId());
        dsmsPoor.setStatus(modifyPoorStatusDto.getStatus());

        int result = dsmsPoorService.modifyPoorStatusById(dsmsPoor, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 审核特困人员.
     *
     * @param applyPoorDto the apply poor dto
     * @return the wrapper
     */
    @Authorization
    @ValidateAnnotation
    @PostMapping(value = "/apply")
    public Wrapper apply(@CurrentUser DsmsUser login,
                         @Valid @RequestBody ApplyPoorDto applyPoorDto) {

        int result = dsmsPoorService.apply(applyPoorDto, login);
        if (result < 1) {
            return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                    .getMessage("operation.failed", null));
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), result);
    }

    /**
     * 查询人员变动信息
      * @param poorChangeVo
     * @return null
     * @author HD
     * @date 2022/2/18 15:28
     */
    @PostMapping("/queryPoorChange")
    public Wrapper queryPoorChange(@RequestBody PoorChangeVo poorChangeVo){
        List<PoorChangeVo> poorChangeVos = dsmsPoorChangeService.queryPoorChange(poorChangeVo);
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                .getMessage("operation.success", null), new PageInfo<>(poorChangeVos));
    }

    /**
     * 审批特困人员信息变动
     * @param poorChangeVo
     * @return null
     * @author HD
     * @date 2022/2/18 15:28
     */
    @PostMapping("/approvalPoorChange")
    public Wrapper approvalPoorChange(@RequestBody PoorChangeVo poorChangeVo) {
        if (poorChangeVo.getApprovalStatus() == 1) {
            DsmsPoorChange poorChange = dsmsPoorChangeService.selectByKey(poorChangeVo.getId());
            DsmsPoor poor = new DsmsPoor();
            if (poorChange.getStatus() == 0) {
                poor.setId(poorChange.getPoorId());
                if (poorChange.getUnitId() != null) {
                    poor.setUnitId(poorChange.getUnitId());
                    poor.setUnitName(poorChange.getUnitName());
                }
                if (poorChange.getPoorAdressGps() != null) {
                    poor.setLocationWgs(poorChange.getPoorAdressGps());
                    poor.setLocation(poorChange.getLocation());
                }
                if (poorChange.getPoorPic() != null) {
                    poor.setHeadPic(poorChange.getPoorPic());
                }
                Integer result = dsmsPoorService.update(poor);

            }
            if (poorChange.getStatus() == 1) {
                poor.setId(poorChange.getPoorId());
                poor.setStatus("DISABLE");
                Integer result = dsmsPoorService.update(poor);
            }
            if (poorChange.getStatus() == 2) {
                poor.setId(poorChange.getPoorId());
                poor.setIsDie(1);
                poor.setStatus("DISABLE");
                Integer result = dsmsPoorService.update(poor);
            }
            DsmsPoorChange dsmsPoorChange = new DsmsPoorChange();
            dsmsPoorChange.setId(poorChangeVo.getId());
            dsmsPoorChange.setApprovalStatus(1);
            Integer result = dsmsPoorChangeService.update(dsmsPoorChange);
            return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                    .getMessage("operation.success", null), result);
        }
        if (poorChangeVo.getApprovalStatus() == 2) {
            DsmsPoorChange dsmsPoorChange = new DsmsPoorChange();
            dsmsPoorChange.setId(poorChangeVo.getId());
            dsmsPoorChange.setApprovalStatus(2);
            dsmsPoorChange.setRemark(poorChangeVo.getRemark());
            Integer result = dsmsPoorChangeService.update(dsmsPoorChange);
            return WrapMapper.wrap(Wrapper.SUCCESS_CODE, csunMessageSource
                    .getMessage("operation.success", null), result);
        }
        return WrapMapper.wrap(Wrapper.ERROR_CODE, csunMessageSource
                .getMessage("operation.failed", null));
    }

    @Transactional
    @PostMapping(consumes = "multipart/form-data", value = "/importPoor")
    public Wrapper importPoor(HttpServletRequest request) throws Exception {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");
        ReadExcelUtils excelReader = new ReadExcelUtils(file.getInputStream());
        Map<Integer, Map<Integer, Object>> map = excelReader.readExcelContent();
        log.info("特困人员上传,param:{}", map.toString());

        for (int i = 2; i <= map.size(); i++) {
            String town = (String) map.get(i).get(0);
            String village = (String) map.get(i).get(1);
            String unitName = (String) map.get(i).get(2);
            String name = (String) map.get(i).get(3);
            String sex = (String) map.get(i).get(4);
            String idCard = (String) map.get(i).get(5);
            String selfCareAbility = (String) map.get(i).get(6);
            String supportWay = (String) map.get(i).get(7);
            String isDisability = (String) map.get(i).get(8);
            String disabilityType = (String) map.get(i).get(9);
            String disabilityDetails = (String) map.get(i).get(10);
            String location = (String) map.get(i).get(11);
            String isLivingAlone = (String) map.get(i).get(12);
            String cohabitantName = (String) map.get(i).get(13);
            String checkIn = DateUtil.dateToStr1((Date) map.get(i).get(14));
            String phone = (String) map.get(i).get(15);
            String kinsfolkName = (String) map.get(i).get(16);
            String kinsfolkRelation = (String) map.get(i).get(17);
            String kinsfolkPhone = (String) map.get(i).get(18);


            PoorDto poorDto = new PoorDto();

            Example example = new Example(DsmsUnit.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("name", unitName);
            List<DsmsUnit> dsmsUnits = dsmsUnitService.selectByExample(example);
            if (!CollectionUtils.isEmpty(dsmsUnits)) {
                poorDto.setUnitId(dsmsUnits.get(0).getId());
            } else {
//                throw new BusinessException(ErrorCodeEnum.GB10051004, unitName);
            }

            Example example1 = new Example(DsmsUnit.class);
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("name", town);
            List<DsmsUnit> dsmsUnits1 = dsmsUnitService.selectByExample(example1);
            if (!CollectionUtils.isEmpty(dsmsUnits1)) {
                poorDto.setTown(dsmsUnits1.get(0).getId());
            } else {
                throw new BusinessException(ErrorCodeEnum.GB10051004, unitName);
            }

            Example example2 = new Example(DsmsUnit.class);
            Example.Criteria criteria2 = example2.createCriteria();
            criteria2.andEqualTo("name", village);
            List<DsmsUnit> dsmsUnits2 = dsmsUnitService.selectByExample(example2);
            if (!CollectionUtils.isEmpty(dsmsUnits2)) {
                poorDto.setVillage(dsmsUnits2.get(0).getId());
            } else {
                throw new BusinessException(ErrorCodeEnum.GB10051004, unitName);
            }

            poorDto.setName(name);
            poorDto.setSex(sex.equals("男") ? 1 : 0);
            poorDto.setIdCard(idCard);
            poorDto.setSelfCareAbility(this.querySelfCareAbility(selfCareAbility));
            poorDto.setSupportWay(supportWay.equals("集中") ? 1 : 2);
            poorDto.setIsDisability(isDisability.equals("是") ? 1 : 0);
            poorDto.setDisabilityType(DisabilityTypeEnum.getEunm(disabilityType).code());
            poorDto.setDisabilityDetails(DisabilityDetailsEnum.getEunm(disabilityDetails).code());
            poorDto.setLocation(location);
            poorDto.setIsLivingAlone(isLivingAlone.equals("是") ? "1" : "0");
            poorDto.setCohabitantName(cohabitantName);
            poorDto.setCheckIn(checkIn);
            poorDto.setPhone(phone);
            poorDto.setKinsfolkName(kinsfolkName);
            poorDto.setKinsfolkRelation(kinsfolkRelation);
            poorDto.setKinsfolkPhone(kinsfolkPhone);

            String birthday = this.queryBirthday(idCard);
            poorDto.setBirthday(birthday);

            dsmsPoorService.save(poorDto, null);
        }

        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, "导入成功");
    }

    @GetMapping(value = "/exportModelPoor")
    public void exportModelPool(HttpServletResponse response) throws Exception {
        ByteArrayOutputStream outputStream = null;
        String file_name = URLEncoder.encode("特困人员-", "UTF-8");
        //生成Excel
        outputStream = getModelDevGeomagneticExcelByte();
        byte[] byteArray = outputStream.toByteArray();
        response.setCharacterEncoding("UTF-8");
        response.addHeader("Content-Disposition",
                "attachment;fileName=" + file_name + DateUtil.getNowTime() + ".xls");
        response.getOutputStream().write(byteArray);
    }


    private ByteArrayOutputStream getModelDevGeomagneticExcelByte() throws Exception {
        // 1.读取工作簿
        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("excelModel/poor.xls");
        //获取模版
        HSSFWorkbook workbook = new HSSFWorkbook(is);
        //得到工作表
        HSSFSheet sheet = workbook.getSheetAt(0);
        //从第2行开始
        is.close();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return baos;
    }


    private int querySelfCareAbility(String selfCareAbilityStr) {
        if (selfCareAbilityStr.equals("全失能")) {
            return 1;
        } else if (selfCareAbilityStr.equals("半失能")) {
            return 2;
        } else if (selfCareAbilityStr.equals("全自理")) {
            return 3;
        }
        return 0;
    }


    /**
     *  导入人员变动表
     */
    @PostMapping(consumes = "multipart/form-data", value = "/importChangePoor")
    public Wrapper importChangePoor(HttpServletRequest request, @CurrentUser DsmsUser login) throws Exception {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");
        ReadExcelUtils excelReader = new ReadExcelUtils(file.getInputStream());
        Map<Integer, Map<Integer, Object>> map = excelReader.readExcelContent();
        log.info("特困人员变动表上传,param:{}", map.toString());


        List<String> idCards = new ArrayList<>();
        for (int i = 1; i <= map.size(); i++) {
            String idCard = (String) map.get(i).get(4);
            idCards.add(idCard);

//            if (idCard != null) {
//                Example example = new Example(DsmsPoor.class);
//                Example.Criteria criteria = example.createCriteria();
//                criteria.andEqualTo("idCard", idCard);
//                List<DsmsPoor> dsmsPoors = dsmsPoorService.selectByExample(example);
//                if (!CollectionUtils.isEmpty(dsmsPoors)) {
//                    dsmsPoors.get(0).setStatus("DISABLE");
//                    dsmsPoorService.update(dsmsPoors.get(0));
//                }
//            }
        }
        if (!CollectionUtils.isEmpty(idCards)) {
            dsmsPoorService.update(idCards);
            dsmsPoorService.update1(idCards);
        }
        return WrapMapper.wrap(Wrapper.SUCCESS_CODE, "导入成功");
    }

    private String queryBirthday(String idCard) {
        String birthday = "";
        String sfzh = idCard;
        // 身份证号不为空
        if (sfzh.length() == 15) {
            birthday = "19" + sfzh.substring(6, 8) + "-" + sfzh.substring(8, 10) + "-" + sfzh.substring(10, 12);
        } else if (sfzh.length() == 18) {
            birthday = sfzh.substring(6, 10) + "-" + sfzh.substring(10, 12) + "-" + sfzh.substring(12, 14);
        }
        return birthday;
    }

}
